package com.zoro.barn.business.service.login.business.normalpassword.util.token;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.NumericNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.zoro.barn.commons.tools.json.JsonUtil;

import java.util.Date;
import java.util.Iterator;
import java.util.Map;

/**
 * @author zhaoxingwu
 */
public class TokenPayloadBuilder {

    private final TokenPayload tokenObject;

    public TokenPayloadBuilder(TokenPayload tokenObject) {
        this.tokenObject = tokenObject;
    }

    /**
     * 过期时间
     *
     * @param value 过期时间
     * @return builder
     */
    public TokenPayloadBuilder exp(long value) {
        if (value <= 0) {
            throw new RuntimeException("exp can not less than zero");
        }
        tokenObject.put("exp", value);
        return this;
    }

    public TokenPayloadBuilder iss(String value) {
        tokenObject.put("iss", value);
        return this;
    }
    /**
     * 生效时间
     *
     * @param value 生效时间
     * @return builder
     */
    public TokenPayloadBuilder nbf(Date value) {
        tokenObject.put("nbf", value.getTime());
        return this;
    }

    public TokenPayloadBuilder nbf() {
        return this.nbf(new Date());
    }

    public TokenPayloadBuilder sub(String value) {
        tokenObject.put("sub", value);
        return this;
    }

    public TokenPayloadBuilder aud(String value) {
        tokenObject.put("aud", value);
        return this;
    }

    /**
     * 签发时间
     *
     * @param value 签发时间
     * @return builder
     */
    public TokenPayloadBuilder iat(Date value) {
        tokenObject.put("iat", value.getTime());
        return this;
    }

    public TokenPayloadBuilder iat() {
        this.iat(new Date());
        return this;
    }

    public TokenPayloadBuilder jti(String value) {
        tokenObject.put("jti", value);
        return this;
    }

    public TokenPayloadBuilder customized(String name, Object value) {
        tokenObject.put(name, value);
        return this;
    }

    public TokenPayloadBuilder from(Map<String, Object> source) {
        this.tokenObject.putAll(source);
        return this;
    }
    public TokenPayloadBuilder from(ObjectNode source) {
        Iterator<Map.Entry<String, JsonNode>> entryIterator = source.fields();
        while (entryIterator.hasNext()) {
            Map.Entry<String, JsonNode> entry = entryIterator.next();
            JsonNode node = entry.getValue();
            if (node instanceof TextNode) {
                this.tokenObject.put(entry.getKey(), node.asText());
            } else if (node instanceof NumericNode) {
                this.tokenObject.put(entry.getKey(), node.asLong());
            }
        }
        return this;
    }

    public String build() {
        try {
            return JsonUtil.toString(tokenObject);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
    public TokenPayload buildObject() {
        return this.tokenObject;
    }
}
